/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.merak.core.text.template;

import java.lang.reflect.Method;
import java.util.Date;

import org.merak.core.annotation.Skip;
import org.merak.core.annotation.Style;

public class TemplateProperty implements Comparable<TemplateProperty> {

    //~ Attributes /////////////////////////////////////////////////////////////////////////////////
	//**********************************************************************************************
	private String   name    = null;
	private Class<?> type    = null;
	private String   prefix  = null;
	private Method   getter  = null;
	private Method   setter  = null;
	private Style    style   = null;
	private boolean  rawType = false;

    //~ Methods ////////////////////////////////////////////////////////////////////////////////////
	//**********************************************************************************************
	public String getName() {
		return this.name;
	}
	//**********************************************************************************************
	public void setName(String name) {
		this.name = name;
	}
	//**********************************************************************************************
	@Skip
	public Class<?> getType() {
		return this.type;
	}
	//**********************************************************************************************
	public void setType(Class<?> clazz) {

		this.type    = clazz;
		this.rawType = clazz.isPrimitive()
				    || Number.class.isAssignableFrom(clazz)
				    || Boolean.class.isAssignableFrom(clazz)
				    || Character.class.isAssignableFrom(clazz)
				    || CharSequence.class.isAssignableFrom(clazz)
				    || clazz.isEnum()
				    || Date.class.isAssignableFrom(clazz);

	}
	//**********************************************************************************************
	@Skip
	public String getPrefix() {
		return this.prefix;
	}
	//**********************************************************************************************
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
	//**********************************************************************************************
	@Skip
	public Method getGetter() {
		return this.getter;
	}
	//**********************************************************************************************
	public void setGetter(Method getter) {
		this.getter = getter;
	}
	//**********************************************************************************************
	@Skip
	public Method getSetter() {
		return this.setter;
	}
	//**********************************************************************************************
	public void setSetter(Method setter) {
		this.setter = setter;
	}
	//**********************************************************************************************
	@Skip
	public Style getStyle() {
		return this.style;
	}
	//**********************************************************************************************
	public void setStyle(Style style) {

		this.style = style;

	}
	//**********************************************************************************************
	@Skip
	public boolean isRawType() {
		return this.rawType;
	}
	//**********************************************************************************************
	@Skip
	public boolean isFinal() {
		return this.setter == null;
	}
	//**********************************************************************************************
	@Skip
	public String getCapitalName() {
		return Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1);
	}
	//**********************************************************************************************
	@Skip
	public boolean hasPrefix(String prefix) {
		return this.prefix.equals(prefix);
	}
	//**********************************************************************************************
	public void set(Object obj,Object value) {

		try {
			this.setter.invoke(obj,value);
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
	//**********************************************************************************************
	public Object get(Object obj) {

		try {
			return this.getter.invoke(obj);
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
	//**********************************************************************************************
	@Override
	public int compareTo(TemplateProperty other) {
		return this.getName().compareTo(other.getName());
	}
	//**********************************************************************************************
}
